<?php
class UserContentBehavior extends ModelBehavior
{
	private $_defaultSettings = array(
			'blockable' => false,
			'blockingCallback' => true, 
			'reportable' => false,
			'reportingCallback' => true,
			'badwordFilter' => false, 
			'fieldsToFilter' => array(),
	);
	var $settings;
	var $presentUser = null;
	private $cachekey = 'user_content_';
	private $modelToActivate = array('blockable'=>'Users.BlockedItem','reportable'=>'Users.ReportedItem');
	
	/**
	 * (non-PHPdoc)
	 * @see cake/libs/model/ModelBehavior#setup($model, $config)
	 */
	function setup(AppModel $model,$config = array())
	{
		$this->settings[$model->alias] = am($this->_defaultSettings,$config);
		$this->activateContentModel($this->settings[$model->alias],$model);
		extract($this->settings[$model->alias]);
		$belongsTo = $posterModels;
		if(is_string($posterModels))
		{
			$belongsTo = array($posterModels);
		}
		//$belongsTo = array_unique($belongsTo);
		//pr($this->settings);
		$this->settings[$model->alias]['posterModels'] = array();
		foreach($belongsTo as $key => $userModel)
		{
			$config = array(); 
			if(is_array($userModel))
			{
				$config = $userModel;
				$userModel = $key;
			}
			$this->settings[$model->alias]['posterModels'][] = $userModel; 
			$userModelAlias = end(explode('.', $userModel));
			$counterScope = array();
			if(isset($model->belongsTo[$userModelAlias]) && isset($model->belongsTo[$userModelAlias]['counterScope']))
			{
				$counterScope = $model->belongsTo[$userModelAlias]['counterScope'];
			}
			if(!empty($counterScope))
			{
				$config['counterScope'] = $counterScope;
			}
			
			$config = am(array('class' => $userModel,'counterCache' => true),$config);
			$model->bindModel(array(
				'belongsTo' => array($userModelAlias => $config)), false);
			$userModelObj = cri($userModel);
			
			if(!isset($userModelObj->hasMany[$model->alias]))
			{
				$userModelObj->bindModel(array(
					'hasMany' => array(
						$model->alias => array(
							'className' => $model->className,
							'foreignKey' => $userModelObj->foreignKey,
							'dependent' => false,
							'conditions' => '',
							'fields' => '',
							'order' => '',
							'limit' => '',
							'offset' => '',
							'exclusive' => '',
							'finderQuery' => '',
							'counterQuery' => ''
						))
				), false);							
			}
		}
		
		// add additional field related to poster here
		$oldAddFields = $model->additionalFields;
		$model->additionalFields = array('poster_class', 'poster_entity', 'poster');
		$model->additionalFields = am($model->additionalFields, $oldAddFields);
	}
	
	function poster_class($model, $record)
	{
		extract($this->settings[$model->alias]);
		$posterModelKeysToCheck = array_map(array($this, '_convertToKeys'), $posterModels);
		$keyToModelClassName = array_combine($posterModelKeysToCheck, $posterModels);
		$userModelClass = null;
		foreach($posterModelKeysToCheck as $key)
		{
			if(isset($record[$model->alias][$key]) && is_numeric($record[$model->alias][$key]) && !empty($record[$model->alias][$key]))
			{
				$userModelClass = $keyToModelClassName[$key];
				break;
			}
		}		
		return $userModelClass;
	}
	
	function poster_entity($model, $record)
	{
		if(!isset($record[$model->alias]['poster_class']))
			return false;
		$posterClass = $record[$model->alias]['poster_class'];
		if(strpos($posterClass, '.'))
		{
			return end(explode('.', $posterClass));
		}
		return $posterClass;
	}
	
	function poster(AppModel $model, $record)
	{
		if(!isset($record[$model->alias]['poster_class']))
		{
			return false;
		}
		$options = array('time'=>"+2 minutes");
		$userModelObj = cri($record[$model->alias]['poster_class']);
		$userModelObj->recursive = -1;
		$userId = $record[$model->alias][$userModelObj->foreignKey];
		$cacheKey = 'poster_info';
		GigaCache::set(array('path'=>CACHE,));
		$poster = GigaModelCache::read($userModelObj->alias,$userId,$cacheKey,$options);
		if($poster==false)
		{
			$poster = $userModelObj->findById($userId);
			$poster = $poster[$record[$model->alias]['poster_entity']];
			GigaModelCache::write($userModelObj->alias,$userId,$cacheKey,$poster,$options);
		}
		return $poster;
	}	
	
	function _convertToKeys($modelAlias)
	{
		if(strpos($modelAlias, '.'))
			$modelAlias = end(explode('.', $modelAlias));
		return Inflector::underscore($modelAlias).'_id';
	}
	
	/**
	 * (non-PHPdoc)
	 * @see cake/libs/model/ModelBehavior#beforeFind($model, $query)
	 */
	function beforeFind(&$model,$queryData)
	{
		if(isset($queryData['user_id']))
		$this->setPresentUser($model,$queryData['user_id']);
		if(!is_null($this->presentUser) && $this->settings[$model->alias]['blockable']==true && isset($queryData['unblock']) && $queryData['unblock'] == true)
		{
			$queryData = $this->addBlockingQuery($model,$queryData);
		}
		return $queryData;
	}
	/**
	 * Add Query For Restricting Blocked Item
	 * @param $model
	 * @param $queryData
	 * @return unknown_type
	 */
	function addBlockingQuery($model,$queryData)
	{
		if(is_null($this->presentUser))
		return $queryData;
		$blockedItems  = $this->findBlockedItems($model,$this->presentUser);
		if(!$blockedItems || count($blockedItems) == 0)
		return $queryData;
		//using string to prevent any sort of key ambiguity
		$condition = $model->alias.'.'.$model->primaryKey.' NOT IN ('.implode(',',$blockedItems).')';
		if(is_array($queryData['conditions']))
		{
			$queryData['conditions'][] = $condition;
		}else if(is_string($queryData['conditions']) && strlen($queryData['conditions']) > 0)
		$queryData['conditions'] .= 'AND '.$condition;
		else
		$queryData['conditions'] .= $condition;
		return $queryData;
	}
	/**
	 * Activate Required Models.
	 * @param $config
	 * @return unknown_type
	 */
	function activateContentModel($config,$m)
	{
		foreach($this->modelToActivate as $action => $modelName)
		{
			if(isset($config[$action]) && $config[$action] == true)
			{
				$modelObj =& ClassRegistry::init($modelName);
				$this->{$modelObj->alias} = $modelObj;
				unset($modelObj);
			}
		}
	}
	/**
	 * Find List of blocked items for particular user
	 * @param $model
	 * @param $userId
	 * @return unknown_type
	 */
	function findBlockedItems($model,$userId=null)
	{
		if(is_null($userId))
		$userId = $this->presentUser;
		return $this->BlockedItem->findBlockedItems($model->alias,$userId);
	}


	/**
	 * Save Blocked Item For particuakr user
	 * @param $model
	 * @param $itemId
	 * @param $userId
	 * @return unknown_type
	 */
	function blockItems($model,$itemId = array(),$userId = null)
	{
		if(is_null($userId))
		$userId = $this->presentUser;
		return $this->BlockedItem->blockItems($model->alias,$itemId,$userId);
	}
	/**
	 * Delete Items from blockItems
	 * @param $model
	 * @param $userId
	 * @param $itemId
	 * @return unknown_type
	 */
	function removeBlockedItem($model,$itemId = array(),$userId=null)
	{
		if(is_null($userId))
		$userId = $this->presentUser;
		return $this->BlockedItem->removeBlockedItem($model->alias,$itemId,$userId);
	}
	
	function beforeSave($model,$options)
	{
		extract($this->settings[$model->alias]);
		if($model->_isNew() == true)
		{
			$posterModelKeysToCheck = array_map(array($this, '_convertToKeys'), $posterModels);
			$ownerKeyPresent = false;
			//first checking that directly setting the owner_id i.e. user_id
			foreach($posterModelKeysToCheck as $posterModel)
			{
				if(isset($model->data[$model->alias][$posterModel]) && is_numeric($model->data[$model->alias][$posterModel]))
				{
						$ownerKeyPresent = true;
						break;
				}
			}
			if($ownerKeyPresent == false)
			{
				//getting value of owner from key owner and owner_id
				$value = $this->getOwnerKey($model,$model->data);
				if($value!==false)//merges onnly on valid return
				{
					$model->data[$model->alias] = am($model->data[$model->alias],$value);
				}
			}
		}
		$badWords = cr('UserContentConfig.bad_words');
		if($badWords)
		{
			$badWords = explode("\n",$badWords);
		}
		if($badwordFilter == true && !empty($fieldsToFilter) && !empty($badWords))
		{
			foreach($fieldsToFilter as $field)
			{
				if(isset($model->data[$model->alias][$field]) && $model->data[$model->alias][$field]!= '')
				{
					foreach($badWords as $badWord)
					{
						if(trim($badWord) != '')
						{
							$model->data[$model->alias][$field] = str_ireplace(trim($badWord),'****',$model->data[$model->alias][$field]);
						}
					}					
				}
			}
		}		
		//code to check bad words ends here.
		return true;
	}
	/**
	 * return owner value 
	 * like array('user_id'=>1);
	 * Saves from hassle of cheking of different type of user;
	 * @param $model
	 * @param $data
	 * @return unknown_type
	 */
	function getOwnerKey($model,$data)
	{
		if(isset($data[$model->alias]['owner']) && isset($data[$model->alias]['owner_id']))
		{
			$ownerKey = Inflector::underscore($data[$model->alias]['owner']).'_id';
			if($model->hasField($ownerKey))
			{
				return array($ownerKey => $data[$model->alias]['owner_id']);
			}
		}
		return false;
	}
	
	function setPresentUser($model,$userId)
	{
		$this->presentUser = $userId;
	}
	
}
?>